// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: daniel

#include "coin2/exchange/coinone/api_util/auth_key.h"

#include <nlohmann/json.hpp>

#include "coin2/base/base64.h"
#include "coin2/exchange/base/api_util/api_signature.h"
#include "coin2/exchange/base/api_util/nonce_manager.h"

std::string CoinoneBaseAuth::GetPayload(const std::string& query_str) {
  nlohmann::json j;
  if (!query_str.empty()) {
    j = nlohmann::json::parse(query_str);
  }
  j["access_token"] = access_key_;
  j["nonce"] = impl::NonceManager::Get();
  return j.dump();
}

auto CoinoneBaseAuth::GetHeaderSet(const std::string& payload) -> const HeaderSet& {
  CHECK_THROW(!header_set_.empty()) << "Header set is empty";
  auto encoded_payload = impl::base64_encode((unsigned char*)payload.c_str(), payload.size());
  header_set_[0].second = encoded_payload;
  header_set_[1].second =
      ApiSignatureUtil::GetSignatureByHexHmacSHA512(encoded_payload, secret_key_);
  return header_set_;
}

AsioHttpContext* CoinoneRestAuth::CreateRequestByPostWithSignature(
    const std::string& address,
    UrlParamsBuilder* builder) {
  std::string query_string = builder->ComputeQueryString();
  std::string post_body = builder->ComputePostBody();
  std::string target = address;
  if (!query_string.empty()) {
    target += "?" + query_string;
  }
  auto payload = GetPayload(post_body);
  auto ahc =
      AsioHttpContext::NewPost(host_, port_, bind_ip_, target, GetHeaderSet(payload), payload);
  ahc->keep_user_agent = true;

  return ahc;
}
